package htdi.nutz.usermanager.module;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.mail.ImageHtmlEmail;
import org.nutz.aop.interceptor.async.Async;
import org.nutz.dao.Dao;
import org.nutz.ioc.Ioc;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Strings;
import org.nutz.lang.random.R;
import org.nutz.log.Log;
import org.nutz.log.Logs;
import org.nutz.mvc.Mvcs;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.DELETE;
import org.nutz.mvc.annotation.GET;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.POST;
import org.nutz.mvc.annotation.Param;
import org.nutz.mvc.view.HttpStatusView;
import org.nutz.mvc.view.ServerRedirectView;

import htdi.nutz.usermanager.bean.User;
import htdi.nutz.usermanager.util.Toolkit;

@At("/api/v1")
@IocBean
@Ok("json:full")
public class UserModule {

    private static final Log log = Logs.get();

    @Inject
    protected Dao dao;

    @Inject("refer:$ioc")
    protected Ioc ioc;

    // https://gitee.com/how-to-do-it/user-manager/issues/ILBLC
    @POST
    @At("/sign_up")
    public Object signUp(@Param("..") User user) {
        if (Strings.isBlank(user.getEmail()) || !Strings.isEmail(user.getEmail())) {
            return new HttpStatusView(400);
        }
        User _user = dao.fetch(User.class, user.getEmail());
        if (_user != null) { // 存在,就需要检查是否已经激活
            switch (user.getStatus()) {
            case 1:
                // 未激活
                break;
            case 2:
                // 已激活,正常
                return new HttpStatusView(409);
            default:
                break;
            }
        } else {
            user.setPassword("123456");
            user.setStatus(1); // 未激活
            user.setSalt(R.UU32());
            user.setPassword(Toolkit.passwordEncode(user.getPassword(), user.getSalt()));
            dao.insert(user);
        }

        String url = Mvcs.getReq().getRequestURL().toString();
        url = url.substring(0, url.lastIndexOf("/sign_up"));
        sendActiveMail(url, user.getEmail());
        // 需求说要变成201, -_-
        Mvcs.getResp().setStatus(201);
        return user;
    }

    // https://gitee.com/how-to-do-it/user-manager/issues/ILBLQ
    @POST
    public Object login(String email, String password, HttpSession session) {
        if (Strings.isBlank(email) || Strings.isBlank(password) || !Strings.isEmail(email)) {
            return new HttpStatusView(400);
        }
        User user = dao.fetch(User.class, email);
        if (user == null) {
            return new HttpStatusView(401);
        }
        if (user.getStatus() != 2) {
            return new HttpStatusView(401);
        }
        if (Toolkit.passwordEncode(password, user.getSalt()).equals(user.getPassword())) {
            session.setAttribute("me", user);
            return new HttpStatusView(201);
        } else {
            return new HttpStatusView(401);
        }
    }

    // https://gitee.com/how-to-do-it/user-manager/issues/ILBM0
    @Ok("void")
    @GET
    @POST
    public void logout(HttpServletRequest req, HttpServletResponse resp) {
        HttpSession session = req.getSession(false);
        if (session != null)
            session.invalidate();
        resp.setStatus(204);
    }

    // https://gitee.com/how-to-do-it/user-manager/issues/ILBM0
    @Ok("void")
    @DELETE
    public void sessions(HttpServletRequest req, HttpServletResponse resp) {
        logout(req, resp);
    }

    @GET
    public Object active(String token, String password) {
        try {
            String[] tmp = Toolkit._3DES_decode(Toolkit.csKEY, Toolkit.hexstr2bytearray(token)).split(",");
            if (System.currentTimeMillis() - Long.parseLong(tmp[1]) > 30 * 60 * 10000) {
                return HttpStatusView.HTTP_404;
            }
            User user = dao.fetch(User.class, tmp[0]);
            if (user == null) {
                return HttpStatusView.HTTP_404;
            }
            user.setStatus(2);
            dao.update(user, "status");
            if (!Strings.isBlank(password)) {
                user.setPassword(Toolkit.passwordEncode(password, user.getSalt()));
                dao.update(user, "password");
            }
            return new ServerRedirectView("/?msg=active_ok");
        }
        catch (Throwable e) {
            return HttpStatusView.HTTP_404;
        }
    }

    // 需求说要发邮件的
    @Async
    public void sendActiveMail(String fromURL, String email) {
        try {
            // 简单起见,用系统的MAC地址作为key
            // ImageHtmlEmail 请不要使用注入模式，每次使用都需要去Ioc取一下
            ImageHtmlEmail htmlEmail = ioc.get(ImageHtmlEmail.class);
            htmlEmail.setSubject("How to do it in Nutz 用户激活邮件");
            // 请使用自己的邮箱
            htmlEmail.addTo(email);
            String token = email + "," + System.currentTimeMillis() + "," + R.UU32();
            String returnURL = fromURL + "/active?token=" + Toolkit._3DES_encode(Toolkit.csKEY, token.getBytes());
            htmlEmail.setHtmlMsg("点击链接进行激活 " + returnURL + " 链接30分钟有效 默认密码123456");
            log.debug("开始邮件发送 " + email);
            htmlEmail.buildMimeMessage();
            htmlEmail.sendMimeMessage();
            log.debug("邮件发送完毕-请查收！注意有可能进入垃圾收件箱");
        }
        catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }
}
